#ifndef OPENHITLS_KAE_MODES_H
#define OPENHITLS_KAE_MODES_H

#include "bsl_params.h"
#include "crypt_algid.h"
#include "wd.h"
#include "wd_cipher.h"

#define SM4_BLOCK_NUM           4
#define SM4_BLOCK_SIZE          16

#define AES128_BLOCK_NUM        4
#define AES128_BLOCK_SIZE       16

#define AES192_BLOCK_NUM        4
#define AES192_BLOCK_SIZE       24

#define AES256_BLOCK_NUM        4
#define AES256_BLOCK_SIZE       32

#define CIPHER_BLOCK_NUM        4
#define CIPHER_BLOCK_SIZE       (272 * 1024)
#define CIPHER_CACHE_SIZE       1024

typedef struct KAE_Mode_Ctx
{
    struct wd_queue                     queue;
    struct wd_queue_mempool*            pool;
    struct wcrypto_cipher_ctx_setup     setup;
    struct wcrypto_cipher_op_data       opData;
    void*                               cipherCtx;
    uint8_t                             block[CIPHER_CACHE_SIZE];
    uint32_t                            cipherSize;
    uint32_t                            remain;
    int32_t                             pad;
} KAE_Mode_Ctx;

KAE_Mode_Ctx *KAE_Mode_NewCtx(int32_t algId);

int32_t KAE_Mode_InitCtx(KAE_Mode_Ctx *ctx, const uint8_t *key, uint32_t keyLen, const uint8_t *iv, uint32_t ivLen, const BSL_Param *param, bool enc);

int32_t KAE_Mode_Update(KAE_Mode_Ctx *ctx, const uint8_t *in, uint32_t inLen, uint8_t *out, uint32_t *outLen);

int32_t KAE_Mode_Final(KAE_Mode_Ctx *ctx, uint8_t *out, uint32_t *outLen);

int32_t KAE_Mode_Ctrl(KAE_Mode_Ctx *ctx, int32_t cmd, void *val, uint32_t valLen);

int32_t KAE_Mode_Deinit(KAE_Mode_Ctx *ctx);

void KAE_Mode_Free(KAE_Mode_Ctx *ctx);

#endif